/*
 * @Author: your name
 * @Date: 2020-10-23 16:11:41
 * @LastEditTime: 2020-10-26 10:36:13
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \flv.js-master\src\io\speed-sampler.js
 */
// speed-sampler.js-SpeedSampler类-实时网速计算器
// 计算实时网络I/O速度的实用程序类
class SpeedSampler {

    constructor() {
        // _firstCheckpoint 首次检查点
        this._firstCheckpoint = 0;
        // _lastCheckpoint 结尾检查点
        this._lastCheckpoint = 0;
        // _intervalBytes 间隔字节数
        this._intervalBytes = 0;
        // _totalBytes 总字节数
        this._totalBytes = 0;
        // _lastSecondBytes 最后一秒字节数
        this._lastSecondBytes = 0;
        // 相容性检测
        if (self.performance && self.performance.now) {
            // _now 获取当前时间函数
            // 默认 performance.now
            this._now = self.performance.now.bind(self.performance);
        } else {
            // 替补 Date.now
            this._now = Date.now;
        }
    }

    // 方法
    // reset() 重置，其实就是让五个实例属性值全变成 0
    reset() {
        this._firstCheckpoint = this._lastCheckpoint = 0;
        this._totalBytes = this._intervalBytes = 0;
        this._lastSecondBytes = 0;
    }
    // addBytes(bytes) 增加字节数，传入 bytes 参数
    addBytes(bytes) {
        // 如果实例首次检查点为 0
        if (this._firstCheckpoint === 0) {
            // 将实例首次检查点设为现在
            this._firstCheckpoint = this._now();
            // 将实例结尾检查点设为实例首次检查点
            this._lastCheckpoint = this._firstCheckpoint;
            // 将实例间隔字节数加上 bytes
            this._intervalBytes += bytes;
            // 将实例总字节数加上 bytes
            this._totalBytes += bytes;
        // 如果当前时间 - 实例结尾检查点 < 1000
        } else if (this._now() - this._lastCheckpoint < 1000) {
            // 将实例间隔字节数加上 bytes
            this._intervalBytes += bytes;
            // 将实例总字节数加上 bytes
            this._totalBytes += bytes;
        } else {  // duration >= 1000
            // 将实例最后一秒字节数设为实例间隔字节数
            this._lastSecondBytes = this._intervalBytes;
            // 将实例间隔字节数设为 bytes
            this._intervalBytes = bytes;
            // 将实例总字节数加上 bytes
            this._totalBytes += bytes;
            // 将实例结尾检查点设为现在
            this._lastCheckpoint = this._now();
        }
    }
    // 只读属性
    // 当前速率
    get currentKBps() {
        this.addBytes(0);
        // 值为 1000 * 1024 * 间隔字节数/（当前时间 - 结尾检查点）
        let durationSeconds = (this._now() - this._lastCheckpoint) / 1000;
        // 但是为了防止大数溢出
        if (durationSeconds == 0) durationSeconds = 1;
        // 还是（间隔字节数 /（当前时间 - 结尾检查点）/ 1000 ）/ 1024
        return (this._intervalBytes / durationSeconds) / 1024;
    }
    // 最后速率
    get lastSecondKBps() {
        this.addBytes(0);
        // 如果实例的最后一秒字节数不为 0
        if (this._lastSecondBytes !== 0) {
            // 返回实例最后一秒字节数 / 1024
            return this._lastSecondBytes / 1024;
        } else {  // lastSecondBytes === 0
            //  如果实例当前时间 - 实例结尾检查点 >= 500
            if (this._now() - this._lastCheckpoint >= 500) {
                // 如果上次检查点后的时间间隔超过500毫秒
                // 速度几乎是准确的
                // 返回实例当前速率
                return this.currentKBps;
            } else {
                // We don't know
                return 0;
            }
        }
    }
    // 平均速率
    get averageKBps() {
        // 值为（总字节数 /（当前时间 - 首次检查点）/ 1000 ）/ 1024
        let durationSeconds = (this._now() - this._firstCheckpoint) / 1000;
        return (this._totalBytes / durationSeconds) / 1024;
    }
    // 这里要说一句，时间算完要除 1000，单位就从毫秒变成了秒，再套用经典公式 v = sum / time，就得到了网络传输速率，只不过单位是字节，一般我们是以 K 表示，所以还要除 1024
}
// 这个类最关键的方法就是 addBytes，因为在设立初始化检查点后，每次添加字节，都会更新结尾检查点，然后计算一次速率。所以，它是一段一段算速率的。
export default SpeedSampler;